﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using ESRI.ArcGIS.Controls;
using ESRI.ArcGIS.Carto;
using ESRI.ArcGIS.Geodatabase;
using System.Windows.Forms;
using System.Data;
using ESRI.ArcGIS.Geometry;
using ESRI.ArcGIS.DataSourcesGDB;
using ESRI.ArcGIS.esriSystem;
using ESRI.ArcGIS.SystemUI;
using System.Runtime.InteropServices;
//using DIWAGIS.Business.Entities;
using DIWAGIS;

namespace DIWAGIS.Class
{
    public class Editing
    {
        //Declare the Engine editor at the class level.
        //public IEngineEditor m_engineEditor = new EngineEditorClass();
        public static IList<string> lstDataSourceType = new List<string>();
        public static string DBType;

        /// <summary>
        /// Bắt đầu chỉnh sửa file geodatabase
        /// </summary>
        /// <param name="m_mapControl"></param>
        /// <param name="layerEdit"></param>
        public void StartEditingFileGeodatabase(IEngineEditor engineEditor, IMapControl4 m_mapControl, ILayer layerEdit)
        {
            IMap map = m_mapControl.Map;
            IFeatureLayer featureLayer = layerEdit as IFeatureLayer;
            IDataset dataset = featureLayer.FeatureClass as IDataset;
            IWorkspace workspace = dataset.Workspace;
            //((IEngineEditLayers)engineEditor).SetTargetLayer(featureLayer, 0);
            //Bắt đầu chỉnh sửa
            engineEditor.StartEditing(workspace, map);
            //Bắt đầu transaction
            engineEditor.StartOperation();
            if (((IEngineEditLayers)engineEditor).IsEditable(featureLayer) == false)
            {
                Class.clsStaticFunctions.CanhBao("Lớp '" + featureLayer.Name + "' không thể chỉnh sửa!\nKiểm tra lại dữ liệu");
                return;
            }
            else
            {
                //((IEngineEditLayers)engineEditor).SetTargetLayer(featureLayer, 0);
            }
        }

        /// <summary>
        /// Bắt đầu chỉnh sửa SDE database
        /// </summary>
        /// <param name="m_mapControl"></param>
        /// <param name="layerEdit"></param>
        public IWorkspaceEdit StartEditingAttribute_SDE(IWorkspace workspace)
        {
            ////IMap map = m_mapControl.Map;
            ////IFeatureLayer featureLayer = layerEdit as IFeatureLayer;
            //IWorkspaceFactory pWorkspaceFactory = new SdeWorkspaceFactoryClass();

            //// Create a property set and populate it with connection properties.
            //IPropertySet propertySet = new PropertySetClass();
            //propertySet.SetProperty("SERVER", "HUNGNQ");
            //propertySet.SetProperty("INSTANCE", "sde:sqlserver:HUNGNQ\\sql2012");
            //propertySet.SetProperty("DATABASE", "VAWASET");
            //propertySet.SetProperty("USER", "sde");
            //propertySet.SetProperty("PASSWORD", "123456");
            //propertySet.SetProperty("VERSION", "dbo.DEFAULT");

            //// Open the geodatabase using the property set.
            ////IWorkspace workspace = pWorkspaceFactory.Open(propertySet, 0);
            IMultiuserWorkspaceEdit muWorkspaceEdit = (IMultiuserWorkspaceEdit)workspace;
            IWorkspaceEdit workspaceEdit = (IWorkspaceEdit)workspace;
            if (workspaceEdit.IsBeingEdited() == true)
            {
                return workspaceEdit;
            }
            //IFeatureWorkspace iFeatureWorkSpace = (IFeatureWorkspace)workspace;
            //fclass = iFeatureWorkSpace.OpenFeatureClass(fclassName);
            muWorkspaceEdit.StartMultiuserEditing(esriMultiuserEditSessionMode.esriMESMVersioned);
            workspaceEdit.StartEditOperation();
            return workspaceEdit;
        }

        /// <summary>
        /// Kết nối tới CSDL SDE
        /// </summary>
        /// <param name="strServerName"></param>
        /// <param name="strInstance"></param>
        /// <param name="strDatabase"></param>
        /// <param name="strUser"></param>
        /// <param name="strPassword"></param>
        /// <param name="strVersion"></param>
        /// <returns></returns>
        public IWorkspace ConnectSDE(string strServerName, string strInstance, string strDatabase, string strUser, string strPassword, string strVersion)
        {
            IWorkspaceFactory pWorkspaceFactory = new SdeWorkspaceFactoryClass();
            // Create a property set and populate it with connection properties.
            IPropertySet propertySet = new PropertySetClass();
            propertySet.SetProperty("SERVER", strServerName);
            propertySet.SetProperty("INSTANCE", strInstance);
            propertySet.SetProperty("DATABASE", strDatabase);
            propertySet.SetProperty("USER", strUser);
            propertySet.SetProperty("PASSWORD", strPassword);
            propertySet.SetProperty("VERSION", strVersion);
            // Open the geodatabase using the property set.
            IWorkspace workspace = pWorkspaceFactory.Open(propertySet, 0);
            return workspace;
        }

        /// <summary>
        /// Dừng chỉnh sửa shapefile, file geodatabase
        /// </summary>
        public void StopEditing(IEngineEditor engineEditor, ILayer layerEdit)
        {
            IFeatureLayer featureLayer = layerEdit as IFeatureLayer;
            IDataset dataset = featureLayer.FeatureClass as IDataset;
            IWorkspace workspace = dataset.Workspace;
            IWorkspaceEdit workspaceEdit = workspace as IWorkspaceEdit;

            engineEditor.StopOperation(string.Empty);
            if (engineEditor.HasEdits() == false)
                engineEditor.StopEditing(false);
            else
            {
                if (MessageBox.Show("Bạn có muốn lưu những thay đổi?", "Xác nhận lưu", MessageBoxButtons.YesNo) == DialogResult.Yes)
                {
                    try
                    {
                        // Stop the edit session. The saveEdits parameter indicates the edit session
                        // will be committed.
                        engineEditor.StopEditing(true);
                    }
                    catch (COMException comExc)
                    {
                        if (comExc.ErrorCode == (int)fdoError.FDO_E_VERSION_REDEFINED)
                        {
                            // Get the version name.
                            IVersion version = (IVersion)workspace;
                            String versionName = version.VersionName;

                            // Reconcile the version. Modify this code to reconcile and handle conflicts
                            // in a manner appropriate for the specific application.
                            IVersionEdit4 versionEdit4 = (IVersionEdit4)workspace;
                            //versionEdit4.Reconcile4(versionName, true, false, true, true);
                            Boolean HasConflicts = versionEdit4.Reconcile4(versionName, true, false, true, true);
                            if (HasConflicts == true)
                            {
                                Class.clsStaticFunctions.CanhBao("Có xung đột dữ liệu trong quá trình cập nhật dữ liệu");
                            }
                            Boolean canPost = versionEdit4.CanPost();
                            if (canPost == true)
                            {
                                versionEdit4.Post(versionName);
                            }
                            // Stop the edit session.
                            workspaceEdit.StopEditing(true);
                            engineEditor.StopEditing(true);
                        }
                        else
                        {
                            // A different error has occurred. Handle in an appropriate way for the application.
                            workspaceEdit.StopEditing(false);
                            engineEditor.StopEditing(false);
                        }
                    }

                }
                else
                    engineEditor.StopEditing(false);
            }
        }


        /// <summary>
        /// Dừng chỉnh sửa shapefile, file geodatabase
        /// </summary>
        public void StopEditing_WithoutAlert(IEngineEditor engineEditor, ILayer layerEdit)
        {
            IFeatureLayer featureLayer = layerEdit as IFeatureLayer;
            IDataset dataset = featureLayer.FeatureClass as IDataset;
            IWorkspace workspace = dataset.Workspace;
            IWorkspaceEdit workspaceEdit = workspace as IWorkspaceEdit;

            engineEditor.StopOperation(string.Empty);
            if (engineEditor.HasEdits() == false)
                engineEditor.StopEditing(false);
            else
            {
                try
                {
                    // Stop the edit session. The saveEdits parameter indicates the edit session
                    // will be committed.
                    engineEditor.StopEditing(true);
                }
                catch (COMException comExc)
                {
                    if (comExc.ErrorCode == (int)fdoError.FDO_E_VERSION_REDEFINED)
                    {
                        // Get the version name.
                        IVersion version = (IVersion)workspace;
                        String versionName = version.VersionName;

                        // Reconcile the version. Modify this code to reconcile and handle conflicts
                        // in a manner appropriate for the specific application.
                        IVersionEdit4 versionEdit4 = (IVersionEdit4)workspace;
                        //versionEdit4.Reconcile4(versionName, true, false, true, true);
                        Boolean HasConflicts = versionEdit4.Reconcile4(versionName, true, false, true, true);
                        if (HasConflicts == true)
                        {
                            Class.clsStaticFunctions.CanhBao("Có xung đột dữ liệu trong quá trình cập nhật dữ liệu");
                        }
                        Boolean canPost = versionEdit4.CanPost();
                        if (canPost == true)
                        {
                            versionEdit4.Post(versionName);
                        }
                        // Stop the edit session.
                        workspaceEdit.StopEditing(true);
                        engineEditor.StopEditing(true);
                    }
                    else
                    {
                        // A different error has occurred. Handle in an appropriate way for the application.
                        workspaceEdit.StopEditing(false);
                        engineEditor.StopEditing(false);
                    }
                }
            }
        }

        /// <summary>
        /// Dừng chỉnh sửa csdl SDE
        /// </summary>
        /// <param name="workspaceEdit"></param>
        public void StopEditingSDE(IWorkspace workspace)
        {
            IWorkspaceEdit workspaceEdit = workspace as IWorkspaceEdit;
            workspaceEdit.StopEditOperation();
            bool hasEdit = false;
            workspaceEdit.HasEdits(ref hasEdit);
            if (hasEdit == false)
                workspaceEdit.StopEditing(false);
            else
            {
                if (MessageBox.Show("Bạn có muốn lưu những thay đổi?", "Xác nhận lưu", MessageBoxButtons.YesNo) == DialogResult.Yes)
                {
                    try
                    {
                        // Stop the edit session. The saveEdits parameter indicates the edit session
                        // will be committed.
                        workspaceEdit.StopEditing(true);
                    }
                    catch (COMException comExc)
                    {
                        if (comExc.ErrorCode == (int)fdoError.FDO_E_VERSION_REDEFINED)
                        {
                            // Get the version name.
                            IVersion version = (IVersion)workspace;
                            String versionName = version.VersionName;

                            // Reconcile the version. Modify this code to reconcile and handle conflicts
                            // in a manner appropriate for the specific application.
                            IVersionEdit4 versionEdit4 = (IVersionEdit4)workspace;
                            //versionEdit4.Reconcile4(versionName, true, false, true, true);
                            Boolean HasConflicts = versionEdit4.Reconcile4(versionName, true, false, true, true);
                            if (HasConflicts == true)
                            {
                                Class.clsStaticFunctions.CanhBao("Có xung đột dữ liệu trong quá trình cập nhật dữ liệu");
                            }
                            Boolean canPost = versionEdit4.CanPost();
                            if (canPost == true)
                            {
                                versionEdit4.Post(versionName);
                                // Stop the edit session.
                                workspaceEdit.StopEditing(true);
                            }
                            else
                            {
                                workspaceEdit.StopEditing(false);
                            }
                        }
                        else
                        {
                            // A different error has occurred. Handle in an appropriate way for the application.
                            workspaceEdit.StopEditing(false);
                        }
                    }
                }
                else
                    workspaceEdit.StopEditing(false);
            }
        }

        /// <summary>
        /// Dừng chỉnh sửa csdl SDE
        /// </summary>
        /// <param name="workspaceEdit"></param>
        public void StopEditingSDE_WithoutAlert(IWorkspace workspace)
        {
            IWorkspaceEdit2 workspaceEdit = workspace as IWorkspaceEdit2;
            workspaceEdit.StopEditOperation();
            bool hasEdit = false;
            workspaceEdit.HasEdits(ref hasEdit);
            if (hasEdit == false)
                workspaceEdit.StopEditing(false);
            else
            {
                try
                {
                    // Stop the edit session. The saveEdits parameter indicates the edit session
                    // will be committed.
                    workspaceEdit.StopEditing(true);
                }
                catch (COMException comExc)
                {
                    if (comExc.ErrorCode == (int)fdoError.FDO_E_VERSION_REDEFINED)
                    {
                        // Get the version name.
                        IVersion version = (IVersion)workspace;
                        String versionName = version.VersionName;

                        // Reconcile the version. Modify this code to reconcile and handle conflicts
                        // in a manner appropriate for the specific application.
                        IVersionEdit4 versionEdit4 = (IVersionEdit4)workspace;
                        Boolean HasConflicts = versionEdit4.Reconcile4(versionName, true, false, true, true);

                        //Dùng để so sánh sự khác nhau giữa 2 version

                        //IDataChangesEx editDataChanges = workspaceEdit.get_EditDataChanges(esriEditDataChangesType.esriEditDataChangesWithinSession);
                        //IEnumBSTR enumBSTR = editDataChanges.ModifiedClasses;
                        //if (enumBSTR != null)
                        //{
                        //    string classChanges = enumBSTR.Next();
                        //    if (classChanges != string.Empty)
                        //    {
                        //        IDifferenceCursorEx differenceCursor = editDataChanges.ExtractEx(classChanges, esriDifferenceType.esriDifferenceTypeUpdateNoChange);
                        //        int OID;
                        //        IRow SourceRow;
                        //        IRow DifferenceRow;
                        //        ILongArray arrayDifference;
                        //        //int 
                        //        differenceCursor.Next(out OID, out SourceRow, out DifferenceRow, out arrayDifference);
                        //        // Go to each changed field and display the old and new values.
                        //        for (int i = 0; i < SourceRow.Fields.FieldCount; i++)
                        //        {
                        //            //MessageBox.Show(SourceRow.get_Value(i) + " vs " + DifferenceRow.get_Value(i));
                        //            Console.WriteLine("Previous value: {0}", SourceRow.get_Value(i));
                        //            Console.WriteLine("Current value: {0}", DifferenceRow.get_Value(i));
                        //        }
                        //    }
                        //}

                        if (HasConflicts == true)
                        {
                            Class.clsStaticFunctions.CanhBao("Có xung đột dữ liệu trong quá trình cập nhật dữ liệu");
                        }
                        Boolean canPost = versionEdit4.CanPost();
                        if (canPost == true)
                        {
                            versionEdit4.Post(versionName);
                        }
                        // Stop the edit session.
                        workspaceEdit.StopEditing(true);
                    }
                    else
                    {
                        // A different error has occurred. Handle in an appropriate way for the application.
                        workspaceEdit.StopEditing(false);
                    }
                }
            }
        }

        public void SaveEditingSDE(ref IWorkspaceEdit2 workspaceEdit, IWorkspace workspace)
        {
            try
            {
                // Stop the edit session. The saveEdits parameter indicates the edit session
                // will be committed.
                workspaceEdit.StopEditOperation(); //commit transaction
                workspaceEdit.StopEditing(true);
            }
            catch (COMException comExc)
            {
                if (comExc.ErrorCode == (int)fdoError.FDO_E_VERSION_REDEFINED)
                {
                    // Get the version name.
                    IVersion version = (IVersion)workspace;
                    String versionName = version.VersionName;

                    // Reconcile the version. Modify this code to reconcile and handle conflicts
                    // in a manner appropriate for the specific application.
                    IVersionEdit4 versionEdit4 = (IVersionEdit4)workspace;
                    versionEdit4.Reconcile4(versionName, true, false, true, true);

                    //IDataChangesEx editDataChanges = workspaceEdit.get_EditDataChanges(esriEditDataChangesType.esriEditDataChangesWithinSession);
                    //IEnumBSTR enumBSTR = editDataChanges.ModifiedClasses;
                    //if (enumBSTR != null)
                    //{
                    //    string classChanges = enumBSTR.Next();
                    //    if (classChanges != string.Empty)
                    //    {
                    //        IDifferenceCursorEx differenceCursor = editDataChanges.ExtractEx(classChanges, esriDifferenceType.esriDifferenceTypeUpdateUpdate);
                    //        int OID;
                    //        IRow SourceRow;
                    //        IRow DifferenceRow;
                    //        ILongArray arrayDifference;
                    //        //int 
                    //        differenceCursor.Next(out OID, out SourceRow, out DifferenceRow, out arrayDifference);
                    //    }
                    //}

                    Boolean HasConflicts = versionEdit4.Reconcile4(versionName, true, false, true, true);
                    if (HasConflicts == true)
                    {
                        Class.clsStaticFunctions.CanhBao("Có xung đột dữ liệu trong quá trình cập nhật dữ liệu");
                    }
                    Boolean canPost = versionEdit4.CanPost();
                    if (canPost == true)
                    {
                        versionEdit4.Post(versionName);
                        // Stop the edit session.
                        workspaceEdit.StopEditing(true);
                    }
                    else
                    {
                        workspaceEdit.StopEditing(false);
                    }
                }
                else
                {
                    // A different error has occurred. Handle in an appropriate way for the application.
                    workspaceEdit.StopEditing(false);
                }
            }
            IMultiuserWorkspaceEdit muWorkspaceEdit = (IMultiuserWorkspaceEdit)workspace;
            workspaceEdit = workspace as IWorkspaceEdit2;
            muWorkspaceEdit.StartMultiuserEditing(esriMultiuserEditSessionMode.esriMESMVersioned);
            workspaceEdit.StartEditOperation();
        }

        public void SaveEditing(IEngineEditor engineEditor, IMapControl4 m_mapControl, ILayer layerEdit)
        {
            IFeatureLayer featureLayer = layerEdit as IFeatureLayer;
            IDataset dataset = featureLayer.FeatureClass as IDataset;
            IWorkspace workspace = dataset.Workspace;
            IWorkspaceEdit workspaceEdit = workspace as IWorkspaceEdit;
            //Commit transaction
            engineEditor.StopOperation(string.Empty);
            if (engineEditor.HasEdits() == false)
                engineEditor.StopEditing(false);
            else
            {
                try
                {
                    // Stop the edit session. The saveEdits parameter indicates the edit session
                    // will be committed.
                    engineEditor.StopEditing(true);
                }
                catch (COMException comExc)
                {
                    if (comExc.ErrorCode == (int)fdoError.FDO_E_VERSION_REDEFINED)
                    {
                        // Get the version name.
                        IVersion version = (IVersion)workspace;
                        String versionName = version.VersionName;

                        // Reconcile the version. Modify this code to reconcile and handle conflicts
                        // in a manner appropriate for the specific application.
                        IVersionEdit4 versionEdit4 = (IVersionEdit4)workspace;
                        //versionEdit4.Reconcile4(versionName, true, false, true, true);
                        Boolean HasConflicts = versionEdit4.Reconcile4(versionName, true, false, true, true);
                        if (HasConflicts == true)
                        {
                            Class.clsStaticFunctions.CanhBao("Có xung đột dữ liệu trong quá trình cập nhật dữ liệu");
                        }
                        Boolean canPost = versionEdit4.CanPost();
                        if (canPost == true)
                        {
                            versionEdit4.Post(versionName);
                        }
                        // Stop the edit session.
                        workspaceEdit.StopEditing(true);
                        engineEditor.StopEditing(true);
                    }
                    else
                    {
                        // A different error has occurred. Handle in an appropriate way for the application.
                        workspaceEdit.StopEditing(false);
                        engineEditor.StopEditing(false);
                    }
                }
            }
            StartEditingFileGeodatabase(engineEditor, m_mapControl, layerEdit);
        }

        /// <summary>
        /// Get current snap environment
        /// </summary>
        /// <param name="editor"></param>
        /// <param name="tblResult"></param>
        /// <param name="tolerance"></param>
        public void GetSnapEnvironment(IEngineEditor editor, ref DataTable tblResult, ref double tolerance, IMapControl4 mapControl)
        {
            //Khởi tạo table
            IEngineEditLayers editLayers = editor as IEngineEditLayers;
            IFeatureLayer EditLayer = editLayers.TargetLayer;
            IList<ILayer> lstLayer = Class.WorkingWithLayer.GetAllLayer(mapControl);
            DataRow newRow;
            for (int i = 0; i < lstLayer.Count; i++)
            {
                //if (lstLayer[i].Name != EditLayer.Name)
                //{
                newRow = tblResult.NewRow();
                newRow[0] = lstLayer[i].Name;
                newRow[1] = false;
                newRow[2] = false;
                newRow[3] = false;
                tblResult.Rows.Add(newRow);
                //}
            }
            //Lấy những thiết lập đã được set
            IEngineSnapEnvironment snapEnvironment = editor as IEngineSnapEnvironment;
            snapEnvironment.SnapToleranceUnits = esriEngineSnapToleranceUnits.esriEngineSnapTolerancePixels;
            tolerance = snapEnvironment.SnapTolerance;

            int snapAgentCount = snapEnvironment.SnapAgentCount;

            for (int i = 0; i < snapAgentCount; i++)
            {
                IEngineSnapAgent currentSnapAgent = snapEnvironment.get_SnapAgent(i);
                if (currentSnapAgent is IEngineFeatureSnapAgent)
                {
                    IEngineFeatureSnapAgent featureSnapAgent = currentSnapAgent as IEngineFeatureSnapAgent;
                    for (int j = 0; j < tblResult.Rows.Count; j++)
                    {
                        ILayer layer = Class.WorkingWithLayer.GetLayerByName(tblResult.Rows[j]["LayerName"].ToString(), mapControl);
                        if (((IFeatureLayer)layer).FeatureClass.AliasName == featureSnapAgent.Name)
                        {
                            esriGeometryHitPartType hitType = featureSnapAgent.HitType;
                            bool vertex, edge, end;
                            vertex = (hitType & esriGeometryHitPartType.esriGeometryPartVertex) == esriGeometryHitPartType.esriGeometryPartVertex;
                            edge = (hitType & esriGeometryHitPartType.esriGeometryPartBoundary) == esriGeometryHitPartType.esriGeometryPartBoundary;
                            end = (hitType & esriGeometryHitPartType.esriGeometryPartEndpoint) == esriGeometryHitPartType.esriGeometryPartEndpoint;
                            tblResult.Rows[j]["Vertex"] = vertex;
                            tblResult.Rows[j]["Edge"] = edge;
                            tblResult.Rows[j]["EndPoint"] = end;
                            break;
                        }
                    }
                }
            }
        }

        /// <summary>
        /// Thiết lập bắt điểm
        /// </summary>
        /// <param name="editor"></param>
        /// <param name="tblResult"></param>
        /// <param name="tolerance"></param>
        public void SetSnapEnvironment(IEngineEditor editor, DataTable tblResult, double tolerance, IMapControl4 mapControl)
        {

            IFeatureClass feaClass;
            ILayer layer;
            IEngineEditLayers editLayers = editor as IEngineEditLayers;
            IEngineSnapEnvironment snapEnvironment = editor as IEngineSnapEnvironment;
            snapEnvironment.SnapToleranceUnits = esriEngineSnapToleranceUnits.esriEngineSnapTolerancePixels;
            snapEnvironment.SnapTolerance = tolerance;
            ((IEngineEditProperties2)editor).SnapTips = true;
            snapEnvironment.ClearSnapAgents();
            bool vertex, edge, end;
            for (int i = 0; i < tblResult.Rows.Count; i++)
            {
                vertex = (bool)(tblResult.Rows[i]["Vertex"]);
                edge = (bool)(tblResult.Rows[i]["Edge"]);
                end = (bool)(tblResult.Rows[i]["EndPoint"]);
                if ((vertex == true) || (edge == true) || (end == true))
                {
                    layer = Class.WorkingWithLayer.GetLayerByName(tblResult.Rows[i]["LayerName"].ToString(), mapControl);
                    feaClass = ((IFeatureLayer)layer).FeatureClass;
                    IEngineFeatureSnapAgent featureSnapAgent = new EngineFeatureSnap();
                    featureSnapAgent.FeatureClass = feaClass;

                    if ((vertex == true) && (edge == true) && (end == true))
                    {
                        featureSnapAgent.HitType = esriGeometryHitPartType.esriGeometryPartVertex | esriGeometryHitPartType.esriGeometryPartBoundary | esriGeometryHitPartType.esriGeometryPartEndpoint;
                        snapEnvironment.AddSnapAgent(featureSnapAgent);
                    }
                    else if ((vertex == true) && (edge == true) && (end == false))
                    {
                        featureSnapAgent.HitType = esriGeometryHitPartType.esriGeometryPartVertex | esriGeometryHitPartType.esriGeometryPartBoundary;
                        snapEnvironment.AddSnapAgent(featureSnapAgent);
                    }
                    else if ((vertex == true) && (edge == false) && (end == true))
                    {
                        featureSnapAgent.HitType = esriGeometryHitPartType.esriGeometryPartVertex | esriGeometryHitPartType.esriGeometryPartEndpoint;
                        snapEnvironment.AddSnapAgent(featureSnapAgent);
                    }
                    else if ((vertex == true) && (edge == false) && (end == false))
                    {
                        featureSnapAgent.HitType = esriGeometryHitPartType.esriGeometryPartVertex;
                        snapEnvironment.AddSnapAgent(featureSnapAgent);
                    }
                    else if ((vertex == false) && (edge == true) && (end == true))
                    {
                        featureSnapAgent.HitType = esriGeometryHitPartType.esriGeometryPartBoundary | esriGeometryHitPartType.esriGeometryPartEndpoint;
                        snapEnvironment.AddSnapAgent(featureSnapAgent);
                    }
                    else if ((vertex == false) && (edge == true) && (end == false))
                    {
                        featureSnapAgent.HitType = esriGeometryHitPartType.esriGeometryPartBoundary;
                        snapEnvironment.AddSnapAgent(featureSnapAgent);
                    }
                    else if ((vertex == false) && (edge == false) && (end == true))
                    {
                        featureSnapAgent.HitType = esriGeometryHitPartType.esriGeometryPartEndpoint;
                        snapEnvironment.AddSnapAgent(featureSnapAgent);
                    }
                }
            }
        }

        public void AddNewSnapAgent()
        {
            IEngineEditor editor = new EngineEditorClass();
            IEngineEditLayers editLayers = editor as IEngineEditLayers;
            IEngineSnapEnvironment snapEnvironment = editor as IEngineSnapEnvironment;

            //Check that the user is editing; otherwise, there will be no snap agent loaded.
            if (editLayers.TargetLayer == null)
            {
                MessageBox.Show("Vui lòng kích hoạt chế độ chỉnh sửa");
                return;
            }

            //Clear all existing snap agents.
            snapEnvironment.ClearSnapAgents();

            //Create a feature snap agent.
            IEngineFeatureSnapAgent featureSnapAgent = new EngineFeatureSnap();
            IFeatureClass layerFeatureClass = editLayers.TargetLayer.FeatureClass;
            featureSnapAgent.FeatureClass = layerFeatureClass;
            featureSnapAgent.HitType = esriGeometryHitPartType.esriGeometryPartBoundary;

            //Activate only the snap agent for the target layer.
            snapEnvironment.AddSnapAgent(featureSnapAgent);
        }

        /// <summary>
        /// Tạo khóa tự động tăng trong FeatureClass
        /// </summary>
        /// <param name="newFea"></param>
        public void CreateAutoIncreaseID(IFeature newFea)
        {
            //Lấy Tên featureclass của đối tượng
            IFeatureClass fclass = newFea.Class as IFeatureClass;
            IDataset dsetFeature = fclass as IDataset;
            IDataset dsetOngChinh = ((IFeatureLayer)Class.ClassVariables.LopBanDo.lyrDuongOngChinh).FeatureClass as IDataset;
            IDataset dsetOngLong = ((IFeatureLayer)Class.ClassVariables.LopBanDo.lyrOngLong).FeatureClass as IDataset;
            IDataset dsetOngNhanh = ((IFeatureLayer)Class.ClassVariables.LopBanDo.lyrDuongOngNhanh).FeatureClass as IDataset;
            IDataset dsetDongHoKhachHang = ((IFeatureLayer)Class.ClassVariables.LopBanDo.lyrDongHoKH).FeatureClass as IDataset;
            IDataset dsetDongHoTong = ((IFeatureLayer)Class.ClassVariables.LopBanDo.lyrDongHoTong).FeatureClass as IDataset;
            IDataset dsetTramBom = ((IFeatureLayer)Class.ClassVariables.LopBanDo.lyrTramBom).FeatureClass as IDataset;
            IDataset dsetMayBom = ((IFeatureLayer)Class.ClassVariables.LopBanDo.lyrMayBom).FeatureClass as IDataset;
            IDataset dsetVanDieuKhien = ((IFeatureLayer)Class.ClassVariables.LopBanDo.lyrVanDieuKhien).FeatureClass as IDataset;
            IDataset dsetVanHeThong = ((IFeatureLayer)Class.ClassVariables.LopBanDo.lyrVanHeThong).FeatureClass as IDataset;
            IDataset dsetDiemGiamSatThuCong = ((IFeatureLayer)Class.ClassVariables.LopBanDo.lyrGiamSatChatLuongNuoc).FeatureClass as IDataset;
            IDataset dsetDataLogger = ((IFeatureLayer)Class.ClassVariables.LopBanDo.lyrDatalogger).FeatureClass as IDataset;
            IDataset dsetBeChua = ((IFeatureLayer)Class.ClassVariables.LopBanDo.lyrBeChua).FeatureClass as IDataset;
            IDataset dsetDiemDauNoi = ((IFeatureLayer)Class.ClassVariables.LopBanDo.lyrDiemDauNoi).FeatureClass as IDataset;
            IDataset dsetTruCuuHoa = ((IFeatureLayer)Class.ClassVariables.LopBanDo.lyrTruCuuHoa).FeatureClass as IDataset;
            IDataset dsetNhaMayNuoc = ((IFeatureLayer)Class.ClassVariables.LopBanDo.lyrNhaMayNuoc).FeatureClass as IDataset;
            IDataset dsetSuCoMangLuoi = ((IFeatureLayer)Class.ClassVariables.LopBanDo.lyrDiemSuCo).FeatureClass as IDataset;
            IDataset dsetKhuVucCapNuoc = ((IFeatureLayer)Class.ClassVariables.LopBanDo.lyrKhuVucCapNuoc).FeatureClass as IDataset;
            if (dsetFeature.Name == dsetOngChinh.Name)
            {
                IFeatureClass fclassOngChinh = ((IFeatureLayer)Class.ClassVariables.LopBanDo.lyrDuongOngChinh).FeatureClass;
                ICursor cursor = (ICursor)fclassOngChinh.Search(null, false);
                IDataStatistics dataStatistics = new DataStatisticsClass();
                dataStatistics.Field = DIWAGIS.BusinessLayer.Entities.DuongOngChinh.IDDoanOC;
                dataStatistics.Cursor = cursor;
                if (fclassOngChinh.FeatureCount(null) > 1)
                {
                    ESRI.ArcGIS.esriSystem.IStatisticsResults statisticsResults = dataStatistics.Statistics;
                    double MaxIDOngChinh = statisticsResults.Maximum;
                    int indexIDOngChinh = newFea.Fields.FindField(DIWAGIS.BusinessLayer.Entities.DuongOngChinh.IDDoanOC);
                    if (indexIDOngChinh != -1)
                    {
                        if (MaxIDOngChinh > 0)
                        {
                            newFea.set_Value(indexIDOngChinh, MaxIDOngChinh + 1);
                        }
                        else
                        {
                            newFea.set_Value(indexIDOngChinh, 1);
                        }
                        newFea.Store();
                    }
                }
                else
                {
                    //IField field = newFea.Fields.get_Field(1);
                    int indexIDOngChinh = newFea.Fields.FindField(DIWAGIS.BusinessLayer.Entities.DuongOngChinh.IDDoanOC);
                    if (indexIDOngChinh != -1)
                    {
                        newFea.set_Value(indexIDOngChinh, 1);
                        newFea.Store();
                    }
                }
            }
            else if (dsetFeature.Name == dsetOngLong.Name)
            {
                IFeatureClass fclassOngLong = ((IFeatureLayer)Class.ClassVariables.LopBanDo.lyrOngLong).FeatureClass;
                ICursor cursor = (ICursor)fclassOngLong.Search(null, false);
                IDataStatistics dataStatistics = new DataStatisticsClass();
                dataStatistics.Field = DIWAGIS.BusinessLayer.Entities.DuongOngLong.IDOngLong;
                dataStatistics.Cursor = cursor;
                if (fclassOngLong.FeatureCount(null) > 1)
                {
                    ESRI.ArcGIS.esriSystem.IStatisticsResults statisticsResults = dataStatistics.Statistics;
                    double MaxIDOngLong = statisticsResults.Maximum;
                    int indexIDOngLong = newFea.Fields.FindField(DIWAGIS.BusinessLayer.Entities.DuongOngLong.IDOngLong);
                    if (indexIDOngLong != -1)
                    {
                        if (MaxIDOngLong > 0)
                        {
                            newFea.set_Value(indexIDOngLong, MaxIDOngLong + 1);
                        }
                        else
                        {
                            newFea.set_Value(indexIDOngLong, 1);
                        }
                        newFea.Store();
                    }
                }
                else
                {
                    int indexIDOngLong = newFea.Fields.FindField(DIWAGIS.BusinessLayer.Entities.DuongOngLong.IDOngLong);
                    if (indexIDOngLong != -1)
                    {
                        newFea.set_Value(indexIDOngLong, 1);
                        newFea.Store();
                    }
                }
            }
            else if (dsetFeature.Name == dsetOngNhanh.Name)
            {
                IFeatureClass fclassOngNhanh = ((IFeatureLayer)Class.ClassVariables.LopBanDo.lyrDuongOngNhanh).FeatureClass;
                ICursor cursor = (ICursor)fclassOngNhanh.Search(null, false);
                IDataStatistics dataStatistics = new DataStatisticsClass();
                dataStatistics.Field = DIWAGIS.BusinessLayer.Entities.DuongOngNghanh.IDOngNhanh;
                dataStatistics.Cursor = cursor;
                if (fclassOngNhanh.FeatureCount(null) > 1)
                {
                    ESRI.ArcGIS.esriSystem.IStatisticsResults statisticsResults = dataStatistics.Statistics;
                    double MaxIDOngNhanh = statisticsResults.Maximum;
                    int indexIDOngNhanh = newFea.Fields.FindField(DIWAGIS.BusinessLayer.Entities.DuongOngNghanh.IDOngNhanh);
                    if (indexIDOngNhanh != -1)
                    {
                        if (MaxIDOngNhanh > 0)
                        {
                            newFea.set_Value(indexIDOngNhanh, MaxIDOngNhanh + 1);
                        }
                        else
                        {
                            newFea.set_Value(indexIDOngNhanh, 1);
                        }
                        newFea.Store();
                    }
                }
                else
                {
                    int indexIDOngNhanh = newFea.Fields.FindField(DIWAGIS.BusinessLayer.Entities.DuongOngNghanh.IDOngNhanh);
                    if (indexIDOngNhanh != -1)
                    {
                        newFea.set_Value(indexIDOngNhanh, 1);
                        newFea.Store();
                    }
                }
            }
            else if (dsetFeature.Name == dsetDongHoKhachHang.Name)
            {

            }
            else if (dsetFeature.Name == dsetDongHoTong.Name)
            {
                //IFeatureClass fclassDHTong = ((IFeatureLayer)Class.clsStaticVariables.LopBanDo.lyrDongHoTong).FeatureClass;
                //ICursor cursor = (ICursor)fclassDHTong.Search(null, false);
                //IDataStatistics dataStatistics = new DataStatisticsClass();
                //dataStatistics.Field = VAWASET.Business.Entities.DongHoTong.IDDongHoTong;
                //dataStatistics.Cursor = cursor;
                //if (fclassDHTong.FeatureCount(null) > 1)
                //{
                //    ESRI.ArcGIS.esriSystem.IStatisticsResults statisticsResults = dataStatistics.Statistics;
                //    double MaxIDDongHoTong = statisticsResults.Maximum;
                //    int indexIDDongHoTong = newFea.Fields.FindField(VAWASET.Business.Entities.DongHoTong.IDDongHoTong);
                //    if (indexIDDongHoTong != -1)
                //    {
                //        if (MaxIDDongHoTong > 0)
                //        {
                //            newFea.set_Value(indexIDDongHoTong, MaxIDDongHoTong + 1);
                //        }
                //        else
                //        {
                //            newFea.set_Value(indexIDDongHoTong, 1);
                //        }
                //        newFea.Store();
                //    }
                //}
                //else
                //{
                //    int indexIDDongHoTong = newFea.Fields.FindField(VAWASET.Business.Entities.DongHoTong.IDDongHoTong);
                //    if (indexIDDongHoTong != -1)
                //    {
                //        newFea.set_Value(indexIDDongHoTong, 1);
                //        newFea.Store();
                //    }
                //}
            }
            else if (dsetFeature.Name == dsetTramBom.Name)
            {

            }
            else if (dsetFeature.Name == dsetMayBom.Name)
            {

            }
            else if (dsetFeature.Name == dsetVanDieuKhien.Name)
            {

            }
            else if (dsetFeature.Name == dsetVanHeThong.Name)
            {

            }
            else if (dsetFeature.Name == dsetDiemGiamSatThuCong.Name)
            {

            }
            else if (dsetFeature.Name == dsetDataLogger.Name)
            {

            }
            else if (dsetFeature.Name == dsetDiemDauNoi.Name)
            {
                IFeatureClass fclassDiemDauNoi = ((IFeatureLayer)Class.ClassVariables.LopBanDo.lyrDiemDauNoi).FeatureClass;
                ICursor cursor = (ICursor)fclassDiemDauNoi.Search(null, false);
                IDataStatistics dataStatistics = new DataStatisticsClass();
                dataStatistics.Field = DIWAGIS.BusinessLayer.Entities.DiemDauNoi.IDDiemDauNoi;
                dataStatistics.Cursor = cursor;
                if (fclassDiemDauNoi.FeatureCount(null) > 1)
                {
                    ESRI.ArcGIS.esriSystem.IStatisticsResults statisticsResults = dataStatistics.Statistics;
                    double MaxIDDiemDauNoi = statisticsResults.Maximum;
                    int indexIDDiemDauNoi = newFea.Fields.FindField(DIWAGIS.BusinessLayer.Entities.DiemDauNoi.IDDiemDauNoi);
                    if (indexIDDiemDauNoi != -1)
                    {
                        if (MaxIDDiemDauNoi > 0)
                        {
                            newFea.set_Value(indexIDDiemDauNoi, MaxIDDiemDauNoi + 1);
                        }
                        else
                        {
                            newFea.set_Value(indexIDDiemDauNoi, 1);
                        }
                        newFea.Store();
                    }
                }
                else
                {
                    int indexIDDiemDauNoi = newFea.Fields.FindField(DIWAGIS.BusinessLayer.Entities.DiemDauNoi.IDDiemDauNoi);
                    if (indexIDDiemDauNoi != -1)
                    {
                        newFea.set_Value(indexIDDiemDauNoi, 1);
                        newFea.Store();
                    }
                }
            }
        }

        /// <summary>
        /// Tạo khóa tự động tăng trong ITable
        /// </summary>
        /// <param name="newRow"></param>
        /// <param name="itblSource"></param>
        /// <param name="indexField"></param>
        public double CreateAutoIncreaseID(ITable itblSource, int indexField)
        {
            double result = 0.0;
            ICursor cursor = (ICursor)itblSource.Search(null, false);
            IDataStatistics dataStatistics = new DataStatisticsClass();
            dataStatistics.Field = itblSource.Fields.get_Field(indexField).Name;// VAWASET.Business.Entities.DuongOngChinh.IDDoanOC;
            dataStatistics.Cursor = cursor;
            if (itblSource.RowCount(null) > 1)
            {
                ESRI.ArcGIS.esriSystem.IStatisticsResults statisticsResults = dataStatistics.Statistics;
                double MaxID = statisticsResults.Maximum;
                if (indexField != -1)
                {
                    if (MaxID > 0)
                    {
                        result = MaxID + 1;
                    }
                    else
                    {
                        result = 1;
                    }
                }
            }
            else
            {
                if (indexField != -1)
                {
                    result = 1;
                }
            }
            return result;
        }
    }
}
